package com.jia.together.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jia.together.entity.*;
import com.jia.together.entity.vo.LoginVo;
import com.jia.together.entity.vo.MemberOthersVo;
import com.jia.together.entity.vo.PasswordVo;
import com.jia.together.exception.MyException;
import com.jia.together.mapper.MemberMapper;
import com.jia.together.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jia.together.utils.JwtUtil;
import com.jia.together.utils.RedisUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dujiajia
 * @since 2021-02-18
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private BlogService blogService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private MemberCourseService memberCourseService;
    @Autowired
    private MemberBlogService memberBlogService;
    @Autowired
    private MemberFansService memberFansService;


    @Override
    public Map<String, Object> selectPageList(Long pageNum, Long pageSize) {
        Page<Member> page = new Page<>(pageNum,pageSize);
        QueryWrapper<Member> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_create");
        Page<Member> memberPage = baseMapper.selectPage(page, wrapper);
        List<Member> records = memberPage.getRecords();
        long total = memberPage.getTotal();
        Map<String, Object> map = new HashMap<>();
        map.put("records",records);
        map.put("total",total);
        return map;
    }

    @Override
    public Map<String, Object> loginOrRegisterPassword(Member member) {
        String phone = member.getPhone();
        String password = member.getPassword();
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(password)){
            throw new MyException(40000,"手机或密码为空");
        }
        QueryWrapper<Member> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",phone);
        Member myMember = baseMapper.selectOne(wrapper);

        Map<String,Object> finalMap = new HashMap<>();

        // 没有用户注册
        if (myMember == null){
            Integer count = baseMapper.selectCount(null) + 1;
            Member createMember = new Member();
            createMember.setPhone(phone);
            createMember.setPassword(passwordEncoder.encode(password));
            createMember.setLevel(1);
            createMember.setAvatar("https://gulimall-jia.oss-cn-beijing.aliyuncs.com/avatar01.jpg");
            createMember.setNickname("小白丁"+count+"号");
            createMember.setMotto("hello world");
            baseMapper.insert(createMember);
            finalMap.put("message","注册成功");
        }else{
            // 有该用户
            boolean flag = passwordEncoder.matches(password, myMember.getPassword());
            if (!flag){
                throw new MyException(40000,"用户名或密码错误");
            }
            finalMap.put("message","登录成功");
        }
        Map<String,Object> jwtMap = new HashMap<>();
        jwtMap.put("username",phone);
        String jwtToken = JwtUtil.createJwtToken(jwtMap);
        finalMap.put("token",jwtToken);
        return finalMap;
    }

    @Override
    public Map<String, Object> loginOrRegisterCode(LoginVo loginVo) {
        String email = loginVo.getEmail();
        String code = loginVo.getCode();
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(code)){
            throw new MyException(40000,"邮箱或校验码为空");
        }
        QueryWrapper<Member> wrapper = new QueryWrapper<>();
        wrapper.eq("email",email);
        Member member = baseMapper.selectOne(wrapper);

        Map<String,Object> finalMap = new HashMap<>();
        if (member == null){
            throw new MyException(40000,"请先用手机号登录或注册后绑定邮箱后才可使用邮箱登录");
        }else{
            String redisCode = (String) redisUtil.get("CODE_" + email);
            if (code.equals(redisCode)){
                finalMap.put("message","登录成功");
            }else{
                throw new MyException(40000,"邮箱或校验码不正确");
            }
        }
        Map<String,Object> jwtMap = new HashMap<>();
        jwtMap.put("username",email);
        String jwtToken = JwtUtil.createJwtToken(jwtMap);
        finalMap.put("token",jwtToken);
        return finalMap;
    }

    @Override
    public Member selectInfoByToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)){
            throw new MyException(40000,"没有携带token");
        }
        Claims jwtClaims = JwtUtil.getJwtClaims(token);
        String username = (String) jwtClaims.get("username");
        QueryWrapper<Member> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",username).or().eq("email",username);
        Member member = baseMapper.selectOne(wrapper);
        return member;
    }

    @Override
    public MemberOthersVo selectMemberOthers(String id) {
        // 查询文章相关
        QueryWrapper<Blog> blogWrapper = new QueryWrapper<>();
        blogWrapper.eq("member_id",id);
        List<Blog> publishBlogs = blogService.list(blogWrapper);
        QueryWrapper<MemberBlog> memberBlogQueryWrapper = new QueryWrapper<>();
        memberBlogQueryWrapper.eq("member_id",id);
        List<MemberBlog> memberCollectBlogs = memberBlogService.list(memberBlogQueryWrapper);
        memberCollectBlogs.forEach(item->{
            Blog blog = blogService.getById(item.getCollectBlogId());
            if (blog!=null){
                item.setCollectBlogName(blog.getTitle());
            }
        });
        // 查询课程相关
        QueryWrapper<MemberCourse> memberCourseQueryWrapper = new QueryWrapper<>();
        memberCourseQueryWrapper.eq("member_id",id);
        List<MemberCourse> memberCourses = memberCourseService.list(memberCourseQueryWrapper);
        memberCourses.forEach(memberCourse -> {
            Course buyCourse = courseService.getById(memberCourse.getBuyCourseId());
            if(buyCourse != null){
                memberCourse.setBuyCourseName(buyCourse.getTitle());
            }
            Course studyCourse = courseService.getById(memberCourse.getStudyCourseId());
            if(studyCourse != null){
                memberCourse.setStudyCourseName(studyCourse.getTitle());
            }
        });
        List<MemberCourse> memberBuyCourse = memberCourses.stream().filter(item -> {
            return !StringUtils.isEmpty(item.getBuyCourseId());
        }).collect(Collectors.toList());

        List<MemberCourse> memberStudyCourse = memberCourses.stream().filter(item -> {
            return !StringUtils.isEmpty(item.getStudyCourseId());
        }).collect(Collectors.toList());
        // 查询关注相关   你的关注
        QueryWrapper<MemberFans> memberFansQueryWrapper1 = new QueryWrapper<>();
        memberFansQueryWrapper1.eq("member_id",id);
        List<MemberFans> memberFollow = memberFansService.list(memberFansQueryWrapper1);

        // 查询关注相关   你的粉丝
        QueryWrapper<MemberFans> memberFansQueryWrapper2 = new QueryWrapper<>();
        memberFansQueryWrapper2.eq("fans_id",id);
        List<MemberFans> memberFans  = memberFansService.list(memberFansQueryWrapper2);

        MemberOthersVo memberOthersVo = new MemberOthersVo();
        memberOthersVo.setMemberId(id);
        memberOthersVo.setMemberPublishBlog(publishBlogs);
        memberOthersVo.setMemberCollectBlog(memberCollectBlogs);
        memberOthersVo.setMemberBuyCourse(memberBuyCourse);
        memberOthersVo.setMemberStudyCourse(memberStudyCourse);
        // 关注
        memberOthersVo.setMemberFollow(memberFollow);
        // 你的粉丝
        memberOthersVo.setMemberFans(memberFans);

        return memberOthersVo;

    }

    @Override
    public void changePassword(PasswordVo passwordVo) {
        String memberId = passwordVo.getId();
        String oldPassword = passwordVo.getOldPassword();
        String newPassword = passwordVo.getNewPassword();
        Member member = baseMapper.selectById(memberId);

        boolean matches = passwordEncoder.matches(oldPassword,member.getPassword());

        if (!matches){
            throw new MyException(40000,"原密码错误");
        }
        member.setPassword(passwordEncoder.encode(newPassword));
        baseMapper.updateById(member);
    }
}
